To Be Written...
### Load Packages
## Packages
import plotly.express as px
import pandas as pd
import yfinance as yf
import datetime as datetime
from datetime import date
import plotly.graph_objects as go
import qgrid #qgrid.show_grid(dividend_stocks, show_toolbar=True)
import panel as pn
## Load Time Frame
start = datetime.datetime(2019,11,9)
end = date.today()
## Data
stock_list = pd.read_json('stock_list.json')
tickers = pd.read_csv('tickers.csv')
etf_list = pd.read_json('etf_list.json')
etfs_pay_divs = pd.read_csv('etfs_pay_divs.csv')
most_active_companies = pd.read_json('most_active_companies_list.json')
sectors_performance = pd.read_json('sectors_performance_list.json')
most_gainer_companies = pd.read_json('gainer_companies_list.json')
Wealthfront_Stocks = pd.read_csv('WealthFront_stocks.csv')
ESGV_div = pd.read_csv('ESGV_div')
TFI_div = pd.read_csv('TFI_div')
NUEM_div = pd.read_csv('NUEM_div')
OKE_div = pd.read_csv('OKE_div.csv')
MSFT_div = pd.read_csv('MSFT_div')
AXP_div = pd.read_csv('AXP_div')
dividend_stocks = pd.read_csv('dividend_stocks.csv')
NerdWallet = pd.read_csv('NerdWallet_dividend_stock.csv')
MotleyFool = pd.read_csv('MotleyFool_div_stock.csv')
NerdWallet_div = pd.read_csv('Nerdwallet_div_list.csv')
NASDAQ_sectors = pd.read_csv('Sectors_NASDAQ.csv')
##Modify DataFrame
MotleyFool = MotleyFool.drop(columns=['Unnamed: 0'])
NerdWallet = NerdWallet.drop(columns=['Unnamed: 0'])
ETF= stock_list[stock_list['exchangeShortName']=='ETF']
ETF_Table = qgrid.show_grid(ETF, show_toolbar=True)
ETF_Table
## Which markets hold ETFs?
x2 = etf_list['exchangeShortName'].unique()
y2 = etf_list['exchangeShortName'].value_counts()
fig2 = go.Figure(data=[go.Bar(x=x2, y=y2, text=y2)])
etf_markets = fig2.show()
etf_markets
## Which ETFs pay divs?
qgrid.show_grid(etfs_pay_divs, show_toolbar=True)
## Let's visualize some dividend stocks
## Add traces, TFI, ESGV, NUEM, OKE, MSFT, AXP
fig1 = go.Figure()
fig1.add_trace(go.Scatter(x=TFI_div['Date'], y=TFI_div['Dividends'], name='TFI', mode='lines'))
fig1.add_trace(go.Scatter(x=ESGV_div['Date'], y=ESGV_div['Dividends'], name='ESGV', mode='lines'))
fig1.add_trace(go.Scatter(x=AXP_div['Date'], y=AXP_div['Dividends'], name='AXP', mode='lines'))
fig1.add_trace(go.Scatter(x=NUEM_div['Date'], y=NUEM_div['Dividends'], name='NUEM', mode='lines'))
fig1.add_trace(go.Scatter(x=OKE_div['Date'], y=OKE_div['Dividends'], name='OKE', mode='lines'))
fig1.add_trace(go.Scatter(x=MSFT_div['Date'], y=MSFT_div['Dividends'], name='MSFT', mode='lines'))
### Similar Companies by Sector
Stock_Data = pd.read_csv('https://assets.datacamp.com/production/repositories/655/datasets/1304e66b1f9799e1a5eac046ef75cf57bb1dd630/company-stock-movements-2010-2015-incl.csv', index_col = 0)
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import normalize
from sklearn.manifold import TSNE
movements = Stock_Data.values
companies = Stock_Data.index
### Next we’ll use sklearn’s normalize with its default settings to convert all the individual values of the stock movements into the same scale (all values for example could be turned into their equivalent if the whole scale went from -1 to +1) and name this normalized array “normalized_movements”
normalized_movements = normalize(movements)
### After this we’ll start an instance of sklearn’s TSNE() with a learning rate of 50 called “model”, different learning rates have to be tested on different datasets, you can tell when it’s not a good value because it groups all the samples together in the scatterplot. It is normal to try values between 50 and 200.
model = TSNE(learning_rate = 50)
### Now we are going to apply the model to the array we normalized via the .fit_transform() method and we’ll create arrays from the resulting features which will constitute the X and Y coordinates from our scatter plot.
tsne_features = model.fit_transform(normalized_movements)
xs = tsne_features[:,0]
ys = tsne_features[:,1]
### we’ll also use the company names from the arrays we created earlier to label each of the companies within the scatterplot
fig, ax = plt.subplots(figsize = [15, 10])
plt.scatter(xs, ys, alpha = 0.5)
for x, y, company in zip(xs, ys, companies):
plt.annotate(company, (x, y), fontsize=9, alpha=0.75)
plt.tight_layout
plt.show()
## First Tab
pn.extension()
pn.config.sizing_mode='stretch_width'
text = """
If you want to retire through dividend investing, part of your criteria should be the dividend yield. Dividend income investors who focus on getting more dividends will focus on a high dividend yield. A growth investor would stay away from most industrial stocks and spend more time looking through tech stocks.
The more you invest each month and the less you spend, the sooner your portfolio will cover your cost of living.
Younger investors usually invest in growth stocks, while older investors invest in a combination of dividend stocks and bonds. While you should change your portfolio as your plans change, keep tax implications in mind. Selling shares and reporting gains will boost your capital gains tax."""
financials_static = pn.widgets.StaticText(name='Financials Sector', value='Financials: Banks, Investment Funds, Insurance, Loans, Asset Management')
utilities_static = pn.widgets.StaticText(name='Utilities Sector', value='Utilities: Electric, Gas, Water')
consumers_discretionary_static = pn.widgets.StaticText(name='Consumer Discretionary Sector', value='Consumer Discretionary: Retailers, Media, Consumer Services, Auto, Restaurants, Lodging, Entertainment')
consumer_staples_static = pn.widgets.StaticText(name='Consumer Staples Sector', value=' Consumer Staples: Food and Beverages Manufacturing, Household Goods, Personal Products, Household Products, Tobacco')
energy_static = pn.widgets.StaticText(name='Energy Sector', value='Energy: Oil, Gas, Power, Refineries, Pipeline Operators')
healthcare_static = pn.widgets.StaticText(name='Healthcare Sector', value='Healthcare: Biotech, Hospitals, Medical Devices, Pharmaceuticals')
industrials_static = pn.widgets.StaticText(name='Industrials Sector', value='Industrials: Construction, Defense, Aerospace, Machinery, Hand-Held Tools, Transportation')
information_tech_static = pn.widgets.StaticText(name='Information Technology Sector', value='Information Technology: Electronics, Software, Semiconductors, Computer Equipment, Data Storage')
communications_static = pn.widgets.StaticText(name='Communications Sector', value='Communications: Wireless, Cable, Internet Providers')
materials_static = pn.widgets.StaticText(name='Materials Sector', value='Materials: Mining, Chemicals, Raw Materials, Building Materials, Paper Products')
real_estate_static = pn.widgets.StaticText(name='Real Estate Sector', value='Real Estate: Residential, Commercial, Industrial Real Estate')
cyclical_static = pn.widgets.StaticText(name='Cyclical Sectors', value='Cyclical sectors are closely tied to the strength or weakness of athe broader economic backdrop. If the economy is thriving, companies in the cyclical sectors tend to thrive as well. And if the economy is struggling cyclical sectors and companies also tend to struggle. These are considered cyclical sectors: Materials, Consumer Discretionary, Financials, Real Estate')
defensive_static = pn.widgets.StaticText(name='Defensive Sectors', value='Defensive sectors are not as closely tied to what is happening in the broader economy. Companies within these sectors tend to perform pretty steadily, regardless of what is happening in the economy. These are considered defensive sectors: Consumer Staples, Healthcare, Utilities')
sensitive_static = pn.widgets.StaticText(name='Sensitive Sectors', value='In between cyclical and defensive are sectors considered "sensitive". Sensitive sectors move with the overall economy, but not excessively so. These are considered sensitive sectors: Communication Services, Energy, Industrials, Technology')
Intro = pn.Column(
'# Identify your goals as an investor and create a criteria that matches those goals',
pn.layout.Divider(margin=(-20,0,0,0)),
pn.Row(
text,
background='whitesmoke', width=400),
'## Sectors', '#### There are 11 major sectors, as defined by the Global Industry Classification Standards (GICS):',pn.layout.Divider(margin=(-20,0,0,0)),
pn.Row(financials_static, utilities_static, consumers_discretionary_static, consumer_staples_static, energy_static, healthcare_static, industrials_static, information_tech_static, communications_static, materials_static, real_estate_static,
background='whitesmoke'),
'## Sector Types', pn.layout.Divider(margin=(-20,0,0,0)),
pn.Row(
cyclical_static, defensive_static, sensitive_static, background='whitesmoke'))
Intro
### Reactive tables
import param
class ReactiveTables(param.Parameterized):
dataset = param.ObjectSelector(default='stock list', objects=['AMEX','stock list', 'etf list', 'etfs that pay dividends', 'Dividend Stocks','NYSE', 'NASDAQ', 'Mutual Funds','WealthFront Stocks', 'Microsoft', 'American Express', 'ONEOK', 'NerdWallet', 'Motley Fool'])
rows = param.Integer(default=100, bounds=(5,100))
@param.depends('dataset')
def data(self):
if self.dataset == 'stock list':
return stock_list
elif self.dataset == 'etf list':
return etf_list
elif self.dataset == 'etfs that pay dividends':
return etfs_pay_divs
elif self.dataset == 'WealthFront Stocks':
return Wealthfront_Stocks
elif self.dataset == 'Dividend Stocks':
return dividend_stocks
elif self.dataset == 'Microsoft':
return MSFT_div
elif self.dataset == 'American Express':
return AXP_div
elif self.dataset == 'ONEOK':
return OKE_div
elif self.dataset == 'NerdWallet':
return NerdWallet
elif self.dataset == 'AMEX':
return AMEX
elif self.dataset == 'NYSE':
return NYSE
elif self.dataset == 'NASDAQ':
return NASDAQ
elif self.dataset == 'Mutual Funds':
return Mutual_Fund
else:
return MotleyFool
@param.depends('data', 'rows')
def table(self):
return self.data().iloc[:self.rows]
def panel(self):
return pn.Row(
pn.Param(self, name='Tables', width=300, sizing_mode="fixed"),
pn.Column('## Table', self.table, sizing_mode='stretch_width'),
min_height=1500, min_width=1000)
datasets_dropdown = ReactiveTables().panel()
datasets_dropdown
### Option 2 for Datasets Available
pn.extension(sizing_mode='stretch_width')
sectors_table = pn.widgets.Tabulator(NASDAQ_sectors, pagination='remote', layout='fit_columns', width=1300)
sector_filter = pn.widgets.Select(name='Sector Filter', options=['Capital Goods',
'Basic Industries',
'Finance',
'Miscellaneous',
'Health Care',
'Consumer Services',
'Transportation',
'Technology',
'Consumer Durables',
'Consumer Non-Durables',
'Energy',
'Public Utilities'])
def contains_filter(NASDAQ_sectors, pattern, column):
if not pattern:
return NASDAQ_sectors
return NASDAQ_sectors[NASDAQ_sectors['Sector'].str.contains(pattern)]
sectors_table.add_filter(pn.bind(contains_filter, pattern=sector_filter, column='Sector'))
Sector_Filters = pn.Column(sector_filter, sectors_table)
Sector_Filters
WARNING:param.main: DataTabulator was not imported on instantiation and may not render in a notebook. Restart the notebook kernel and ensure you load it as part of the extension using:
pn.extension('tabulator')
### Select a stock
az = pn.widgets.Select(options=list(etfs_pay_divs.SYMBOL.unique()))
az
ticker = az.value
selected_stock = yf.Ticker(ticker)
warning = pn.widgets.StaticText(name='How to Pull the data', value='In order to see the data that you selected, you will need to shift+enter in the cell with ticker, selected_stock and stock_history defined. Then run the cells with pane and pane2, found below')
markdown = pn.pane.Markdown('Markdown display')
link = az.jslink(markdown, value='object')
first_field = pn.Column(pn.Row(az, markdown))
pn.Column(first_field, warning)
pn.extension('plotly')
ticker = az.value
selected_stock = yf.Ticker(ticker)
selected_stock.dividends
selected_stock.info
stock_history = yf.download(ticker, start=start, end=end)
fig1 = go.Figure(data=[go.Candlestick(x=stock_history.index,
open=stock_history['Open'],
high=stock_history['High'],
low=stock_history['Low'],
close=stock_history['Close'])])
fig1.update_layout(
title=az.value,
xaxis_title="Date",
yaxis_title="Price (USD)"
)
pane = pn.pane.Plotly(fig1)
pane
WARNING:param.panel_extension: A HoloViz extension was loaded previously. This means the extension is already initialized and the following Panel extensions could not be properly loaded: ['plotly']. If you are loading custom extensions with pn.extension(...) ensure that this is called before any other HoloViz extension such as hvPlot or HoloViews.
[*********************100%***********************] 1 of 1 completed
###ARIMA Prediction Model
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas.plotting import lag_plot
from datetime import datetime
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
def smape_kun(y_true, y_pred):
return np.mean((np.abs(y_pred - y_true) * 200/ (np.abs(y_pred) + np.abs(y_true))))
train_data, test_data = stock_history[0:int(len(stock_history)*0.8)], stock_history[int(len(stock_history)*0.8):]
test_data = test_data.reset_index()
train_ar = train_data['Open'].values
test_ar = test_data['Open'].values
train_ar = np.nan_to_num(train_ar)
test_ar = np.nan_to_num(test_ar)
history = [x for x in train_ar]
print(type(history))
predictions = list()
for t in range(len(test_ar)):
model = ARIMA(history, order=(5,1,0))
model_fit = model.fit()
output = model_fit.forecast()
yhat = output[0]
predictions.append(yhat)
obs = test_ar[t]
history.append(obs)
#print('predicted=%f, expected=%f' % (yhat, obs))
error = mean_squared_error(test_ar, predictions)
print('Testing Mean Squared Error: %.3f' % error)
error2 = smape_kun(test_ar, predictions)
print('Symmetric mean absolute percentage error: %.3f' % error2)
import plotly.express as px
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
name='Predicted Price', mode='markers+lines', x=test_data['Date'], y=predictions, marker_symbol='circle'))
fig.add_trace(go.Scatter(name='Actual Price', mode='lines', x=test_data['Date'], y=test_data['Open']))
fig.update_layout(title_text="Predicted Prices for Selected Stock")
fig.update_xaxes(rangeslider_visible=True)
pane2= pn.pane.Plotly(fig)
<class 'list'> Testing Mean Squared Error: 0.000 Symmetric mean absolute percentage error: 0.046
pane2
## Individual Stocks Tab
tabs1 = pn.Tabs(('Pick', first_field),
('Info', selected_stock.info),
('Dividends', selected_stock.dividends),
('History', stock_history),
('Time Chart', pane),
('Prediction Chart', pane2),dynamic=True)
tabs1
### Dashboard with Dynamic Tabs
### Dynamic Tabs
tabs = pn.Tabs(('Intro', Intro),
('Companies in Similar Sectors', fig),
('Companies within Sectors', Sector_Filters),
('Datasets Available', datasets_dropdown),
('Individual Stock Analysis', tabs1), dynamic=True)
tabs